using PowerManage.Service;

namespace PowerManage.API.Extensions;

/// <summary>
/// Repository相关扩展
/// </summary>
public static class ServiceExtension
{
    /// <summary>
    /// Repository注入
    /// </summary>
    /// <param name="builder"></param>
    public static void AddPowerManageService(this WebApplicationBuilder builder)
    {
        //添加注入
        //依赖注入有3种方法： 生命周期策略： 瞬态：transient、作用域：scoped、单例：singleton
        //瞬态:无论是不是同一个请求（用一个请求里的不同服务）同一个客户端，每次都是创建新的实例
        //作用域:对于同一个请求返回同一个实例，不同的请求返回不同的实例
        //单例:每次都是获得同一个实例
        //下面的注入方式不可取 如果功能越多，就会有很多相关的Repository，我们重构依赖注入逻辑
        // builder.Services.AddTransient(typeof(IRolePermissionRepository), typeof(RolePermissionRepository));

        //用反射来自动获取并注入
        //1 获取继承BaseRepository的类
        // var assemblies = AppDomain.CurrentDomain.GetAssemblies(); //获取当前应用程序域（AppDomain）中已加载的所有程序集（Assembly）
        var assemblies = AppDomain.CurrentDomain.GetReferenceAssemblies();
        foreach (var assembly in assemblies)
        {
            //检查当前程序集是否包含 BaseRepository 类
            //typeof(BaseRepository).Assembly 获取 BaseRepository 类所在的程序集。这里的作用是仅处理包含 BaseRepository 类的程序集
            // 如果不加这一判断，代码将会遍历所有引用的程序集，并尝试从中获取继承自 BaseRepository 的类。
            // 这可能会导致不必要的性能开销，因为许多程序集中可能没有 BaseRepository 类。
            // 可能会注册一些不需要的类，导致不必要的依赖注入配置。
            // 加这个判断的意义
            // 提高效率：仅处理包含 BaseRepository 类的程序集，避免遍历所有程序集。
            // 减少错误：确保只注册实际需要的类，避免不必要的注册。
            if (typeof(BaseService).Assembly.Equals(assembly))
            {
                var types = assembly.GetTypes().Where(type => type.BaseType == typeof(BaseService))
                    .ToList(); //筛选出所有继承自 BaseRepository 的类型
                foreach (var typeImpl in types)
                {
                    //2 获取该类所继承的所有接口
                    foreach (var type in typeImpl.GetInterfaces().ToList())
                    {
                        builder.Services.AddTransient(type, typeImpl);
                    }
                }
            }
        }
    }
}